package game.avatar
{
	import flash.display.Bitmap;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	import game.map.VisualMap;
	import starling.core.Starling;
	import starling.display.MovieClip;
	import starling.events.Event;
	import starling.textures.Texture;
	import starling.textures.TextureAtlas;
	import starling.textures.TextureSmoothing;
	
	/**
	 * ...
	 * @author Kirill Pletnev
	 */
	public class Avatar
	{
		// Texture Atlas        
		[Embed(source="../../../media/textures/avatars/defaultAvatar.xml",mimeType="application/octet-stream")]
		private static const AtlasXml:Class;
		
		[Embed(source="../../../media/textures/avatars/defaultAvatar.png")]
		private static const AtlasTexture:Class;
		
		private static const MOVE_NORTH_EAST:String = "northeast";
		private static const MOVE_NORTH_WEST:String = "northwest";
		private static const MOVE_SOUTH_HEAST:String = "southeast";
		private static const MOVE_SOUTH_WEST:String = "southwest";
		
		private static var AVATAR_ANIM_NAME:Vector.<String> = new <String>[MOVE_NORTH_EAST, MOVE_NORTH_WEST, MOVE_SOUTH_HEAST, MOVE_SOUTH_HEAST, MOVE_SOUTH_WEST];
		
		private static const AVATAR_FPS:int = 5;
		private static var _sTextureAtlas:TextureAtlas;
		
		private var _animsData:Object;
		
		private var _textures:Dictionary = new Dictionary();
		
		private var _movieClip:MovieClip;
		
		public function Avatar(visualMap:VisualMap)
		{
			initAnims();
			
			var frames:Vector.<Texture> = getTextureAtlas().getTextures("northeast");
			_movieClip = new MovieClip(frames, 5);
			_movieClip.loop = true;
			_movieClip.x = 100;
			_movieClip.y = 100;
			
			// like any animation, the movie needs to be added to the juggler!
			// this is the recommended way to do that.
			_movieClip.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			_movieClip.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
			
			visualMap.gameObjects.addChild(_movieClip);
		}
		
		private function initAnims():void
		{
			AVATAR_ANIM_NAME.forEach(function(animName:String, index:uint, vec:Vector.<String>):void
				{
					addAnim(animName, getTextureAtlas().getTextures(animName));
				}, this);
		}
		
		private function addAnim(animName:String, textures:Vector.<Texture>):void
		{
			_animsData ||= new Object();
			_animsData[animName] = new MovieClip(textures, AVATAR_FPS);
			
			var anim:MovieClip = _animsData[animName] as MovieClip;
			anim.name = animName;
			anim.smoothing = TextureSmoothing.TRILINEAR;
		}
		
		private function onAddedToStage(event:Event):void
		{
			Starling.juggler.add(_movieClip);
		}
		
		private function onRemovedFromStage(event:Event):void
		{
			Starling.juggler.remove(_movieClip);
		}
		
		public function dispose():void
		{
			_movieClip.removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage);
			_movieClip.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
		
		public function getTextureAtlas():TextureAtlas
		{
			if (_sTextureAtlas == null)
			{
				var texture:Texture = getTexture("AtlasTexture");
				var xml:XML = XML(new AtlasXml());
				_sTextureAtlas = new TextureAtlas(texture, xml);
			}
			
			return _sTextureAtlas;
		}
		
		public function getTexture(name:String):Texture
		{
			if (_textures[name] == undefined)
			{
				var data:Object = new Avatar[name]();
				
				if (data is Bitmap)
				{
					_textures[name] = Texture.fromBitmap(data as Bitmap);
				}
				else if (data is ByteArray)
				{
					_textures[name] = Texture.fromAtfData(data as ByteArray);
				}
			}
			return _textures[name];
		}
	}
}